package com.twm.curator;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.*;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;

import java.util.List;

public class GetNoteChildrenCurator {

    private static CuratorFramework curatorFramework;
    /**
     * 创建会话
     */
    public static void main(String[] args) throws Exception {
        RetryPolicy exponentialBackoffRetry = new ExponentialBackoffRetry(1000, 3);

        //使用fluent变成风格
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("127.0.0.1:2181")
                .sessionTimeoutMs(50000)
                .connectionTimeoutMs(30000)
                .retryPolicy(exponentialBackoffRetry)
                .namespace("base")  //独立的命名空间
                .build();
        client.start();
        curatorFramework = client;
        System.out.println("会话2建立成功");
        //创建节点
        String path = "/netty-provider1";

        List<String> strings = client.getChildren().forPath(path);
        System.out.println("子节点" + strings);

        zkWatch(path);

        String s = client.create().creatingParentContainersIfNeeded()
                .withMode(CreateMode.EPHEMERAL).forPath(path + "/9006", "name".getBytes());
        System.out.println("节点递归创建成功， 节点路径： " + s);
        Thread.sleep(Integer.MAX_VALUE);
    }

    /**
     * 注册监听
     * TreeCache: 可以将指定的路径节点作为根节点（祖先节点），对其所有的子节点操作进行监听，
     * 呈现树形目录的监听，可以设置监听深度，最大监听深度为 int 类型的最大值。
     */
    private static void zkWatch(String path) throws Exception {
        TreeCache treeCache = new TreeCache(curatorFramework, path);

        treeCache.getListenable().addListener(new TreeCacheListener() {
            @Override
            public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
                ChildData eventData = event.getData();
                switch (event.getType()) {
                    case NODE_ADDED:
                        System.out.println(path + "节点添加" + eventData.getPath() + "\t添加数据为：" + new String(eventData.getData()));
                        break;
                    case NODE_UPDATED:
                        System.out.println(eventData.getPath() + "节点数据更新\t更新数据为：" + new String(eventData.getData()) + "\t版本为：" + eventData.getStat().getVersion());
                        break;
                    case NODE_REMOVED:
                        System.out.println(eventData.getPath() + "节点被删除");
                        break;
                    default:
                        break;
                }
            }
        });

        treeCache.start();
    }

    // 获取节点数据
    private static void getZnode(String path) throws Exception {

        byte[] bytes = curatorFramework.getData().forPath(path);                     // 普通查询
        System.out.println(new String(bytes));
    }
}
